<?php
/*------------------------------------------------------------------------
 * Base.php 
 *
 * 基类控制器
 * 	
 * Created on 2017-01-16
 *
 * Author: hwc123 <hwc123@139.com>
 * 
 * Copyright (c) 2017 All rights reserved.
 * ------------------------------------------------------------------------
 */

namespace app\api\controller;
use \think\Request;
use \think\Controller;

class Base extends Controller{
	public $_pagesize  = 10;// 分页数量
	public $_user_id   = 0;// 用户ID
	public $_realname  = '';// 用户姓名
	public $_nickname  = '';// 用户昵称
	public $_mobile    = '';// 用户手机号
	
	function _initialize(){
		//获取接口参数配置信息
		$this->app_id           = isset($_SERVER['HTTP_APP_ID']) ? $_SERVER['HTTP_APP_ID'] : '';
		$this->app_sign         = isset($_SERVER['HTTP_APP_SIGN']) ? strtolower($_SERVER['HTTP_APP_SIGN']) : '';
		$this->app_authtime     = isset($_SERVER['HTTP_APP_AUTHTIME']) ? $_SERVER['HTTP_APP_AUTHTIME'] : '';
		$this->app_version      = isset($_SERVER['HTTP_APP_VERSION']) ? (int)$_SERVER['HTTP_APP_VERSION'] : '';
		$this->app_type         = isset($_SERVER['HTTP_APP_TYPE']) ? $_SERVER['HTTP_APP_TYPE'] : 'unknown';
		$this->app_imei         = isset($_SERVER['HTTP_APP_IMEI']) ? $_SERVER['HTTP_APP_IMEI'] : '';
		$this->app_device       = isset($_SERVER['HTTP_APP_DEVICE']) ? $_SERVER['HTTP_APP_DEVICE'] : '';
		$this->app_os           = isset($_SERVER['HTTP_APP_OS']) ? $_SERVER['HTTP_APP_OS'] : '';
		$this->app_token        = isset($_SERVER['HTTP_APP_TOKEN']) ? $_SERVER['HTTP_APP_TOKEN'] : '';
		$this->app_access_token = isset($_SERVER['HTTP_APP_ACCESS_TOKEN']) ? $_SERVER['HTTP_APP_ACCESS_TOKEN'] : '';
		$this->app_city_id      = isset($_SERVER['HTTP_APP_CITY_ID']) ? $_SERVER['HTTP_APP_CITY_ID'] : '';

		//去掉GET、POST里TP自觉参数
		unset($_GET['_URL_'],$_POST['_URL_']);

		//APP版本号，默认为1
		$this->app_version  = $this->app_version ? $this->app_version : 1;

		//APP类型，默认为unknown
		$this->app_type = strtolower($this->app_type);
		if(!get_type_desc($this->app_type, 'app_type_desc')){
			$this->app_type = 'unknown';
		}
		//城市ID
		$this->app_city_id = $this->app_city_id ? $this->app_city_id : 0;

		//分页参数
		$this->page      = $this->_get('page', '', 1);
		$this->pagesize  = $this->_get('pagesize', '', 10);
		$this->first_row = $this->pagesize * ($this->page - 1);

		//开启接口授权功能
		if(!conf('api_auth_open', 'api')){
			return;
		}

		if(!$this->app_id){
			$this->error('APPID不能为空', '', 500);
		}
		// 签名判断
		if (!$this->app_sign) {
			$this->error('对不起，签名不能为空！', '', 501);
		}
		// 认证时间判断
		if (!is_numeric($this->app_authtime) || strlen($this->app_authtime) != 10) {
			$this->error('对不起，认证时间不能为空或有误！', '', 502);
		}
		if($this->app_type == 'unknown'){
			$this->error('对不起，终端类型有误！');
		}
		// 判断签名是否有误
		if($this->is_api_sign_ok() == false){
			$this->error('对不起，您的签名有误！', '', 504);
		}
	}
	
	protected function _get($name = '', $empty_msg = '', $default_value = '', $is_array_str = false){
		$value = input($name);
		$value = $this->common_field_check($value, $empty_msg, $default_value, $is_array_str);

		$this->assign(str_replace(array('/a'), '', $name), $value);

		return $value;
	}
	protected function _post($name = '', $empty_msg = '', $default_value = '', $is_array_str = false){
		$value = input($name);
		$value = $this->common_field_check($value, $empty_msg, $default_value, $is_array_str);

		$this->assign(str_replace(array('/a'), '', $name), $value);
		
		return $value;
	}
	/**
	 * 通用字段验证
	 * @param  string $field         参数名
	 * @param  string $empty_msg     值为空，提示信息
	 * @param  string $default_value 值为空，默认值
	 * @param  string $is_array_str  返回数组是否转为字符串，多个以逗号分隔
	 */
	protected function common_field_check($value, $empty_msg = '', $default_value = '', $is_array_str = false){
		if(is_array($value)){
			$array_val = implode(',', $value);
			$is_empty  = empty($array_val);
			$value     = $is_array_str ? $array_val : $value;
		}else{
			$is_empty = !trim($value);
			$value    = trim($value);
		}
		
		if($is_empty && $empty_msg){
			$this->error($empty_msg);
		}
		if($is_empty){
			$value = isset($default_value) ? $default_value : '';
		}

		return $value;
	}
	// 请求模型
	protected function request(){
		return Request::instance();
	}
	// 是否为Ajax请求
	protected function isAjax(){
		return $this->request->isAjax();
	}
	// 是否为手机访问
	protected function isMobile(){
		return $this->request->isMobile();
	}
	// 是否为GET请求
	protected function isGet(){
		return $this->request->isGet();
	}
	// 是否为POST请求
	protected function isPost(){
		return $this->request->isPost();
	}

	/**
	 * 获取接口签名
	 */
	protected function get_api_sign(){
		//去掉GET、POST里TP自觉参数
		unset($_GET['_URL_'],$_POST['_URL_']);

		$appkey = $this->get_appkey();
		if(!$appkey){
			return false;
		}
		// $appkey = 'ibuaiVcKdpRxkhJA';
		//获取GET参数
		// $params = $_GET;
		$params = '';
		foreach ($_GET as $key => $value) {
			$params[$key] = urldecode($value);
		}
		$debug['GET'] = $params;
		//获取签名参数
		$params['header_app_id']       = $this->app_id;
		$params['header_app_token']    = $this->app_token;
		$params['header_app_authtime'] = $this->app_authtime;
		$debug['params'] = $params;

		//将数组按abc顺序排序参数
		ksort($params);
		$debug['sort_params'] = $params;

		$url_arr = [];
		foreach ($params as $key => $value) {
			$url_arr[]= $key . '=' . $value;
		}
		$url_str = implode('&', $url_arr);
		
		//将数组转成URL参数字符串
		$url_params = $url_str . '&appkey=' . $appkey;
		$this->app_sign_url_str = $url_params;
		$debug['url_params'] = $url_params;
		//将URL参数字符串进行MD5密码
		$sign = md5($url_params);
		$debug['sign'] = $sign;

		$this->api_sign = $sign;
		// var_dump($debug);
		// var_dump($url_arr);
		// var_dump($url_str);
		// var_dump($sign);
		// exit;

		return $sign;
	}
	/**
	 * 判断接口签名是否正确
	 * @return boolean [description]
	 */
	protected function is_api_sign_ok(){
		$sign = $this->get_api_sign();
		if(!$sign){
			return false;
		}

		return $sign == $this->app_sign;
	}
	/**
	 * 获取APPKEY
	 * @param  string $auth_id 授权ID
	 */
	protected function get_appkey($auth_id = ''){
		$app_id = $auth_id ? $auth_id : $this->app_id;
		if(!$app_id){
			return '';
		}

		$where['app_id'] = $app_id;
		$where['status'] = 1;
		$appkey = db('AppSet')->where($where)->value('app_key');

		return $appkey;
	}

	//获取当前用户城市ID
	protected function city_id(){
		$get_city_id  = $this->_get('city_id');
		$city_id      = $get_city_id ? $get_city_id : $this->app_city_id;
		$user_id      = $this->user_id(false);
		$user_city_id = D('User')->get_user_city_id($user_id);
		$city_id      = $city_id ? $city_id : $user_city_id;
		//默认为云南昭通
		return $city_id ? $city_id : 0;
	}
	//获取用户ID
	protected function user_id($is_login = true){
		$get_token    = $this->_get('token');
		$post_token   = $this->_post('token');
		$access_token = $this->app_access_token;

		//从GET或POST获取token
		$token = $get_token ? $get_token : $post_token;
		//从header获取token
		$token = $this->app_token ? $this->app_token : $token;
		$token = $access_token ? $access_token : $token;

		if(!$token && $is_login){
			$this->error('对不起，您尚未登录！', '', 202);
		}
		// ACCESS TOKEN处理，一次性处理
		if($access_token){
			$info = db('AccessToken')->where(array('access_token' => $access_token))->field('user_id,generate_time')->find();
			if(!$info && $is_login){
				$this->error('登录超时，请重新登录[1]！', '', 202);
			}
			$user_id    = $info['user_id'] ? $info['user_id'] : 0;
			$login_time = $info['generate_time'] ? $info['generate_time'] : 0;
			if(!$login_time){
				$this->error('AccessToken不可用！', '', 202);
			}
			// 设置为过期
			db('AccessToken')->where(array('access_token' => $access_token))->update(array('generate_time' => 0));
		}else{
			$info = db('UserToken')->where(array('token' => $token))->field('user_id,create_time')->find();
			if(!$info && $is_login){
				$this->error('登录超时，请重新登录[2]！', '', 202);
			}
			$user_id    = $info['user_id'] ? $info['user_id'] : 0;
			$login_time = $info['create_time'] ? $info['create_time'] : 0;
		}

		//判断是否超时（2小时）
		$conf_timeout = 7 * 24 * 60 * 60;
		$is_timeout   = (time() - $login_time) > $conf_timeout;
		if($is_timeout && $is_login){
			$this->error('登录超时，请重新登录[3]！', '', 202);
		}
		if($is_login && $info && !$access_token){
			//刷新登录时间
			db('UserToken')->where(array('token' => $token))->update(array('create_time' => time()));
		}
		if($user_id){
			$user = model('User')->user_info($user_id);
		}
		$this->user_realname          = $user['realname'] ? $user['realname'] : '';
		$this->user_mobile            = $user['mobile'] ? $user['mobile'] : '';
		$this->user_email             = $user['email'] ? $user['email'] : '';
		$this->user_nickname          = $user['nickname'] ? $user['nickname'] : '';
		$this->user_province_id       = $user['province_id'] ? $user['province_id'] : 0;
		$this->user_province_name     = $user['province_name'] ? $user['province_name'] : 0;
		$this->user_city_id           = $user['city_id'] ? $user['city_id'] : 0;
		$this->user_city_name         = $user['city_name'] ? $user['city_name'] : 0;
		$this->user_area_id           = $user['area_id'] ? $user['area_id'] : 0;
		$this->user_type              = $user['user_type'] ? $user['user_type'] : 0;//用户类型
		$this->user_sex               = $user['sex'] ? $user['sex'] : 0;//性别
		$this->user_bind_info         = $user['bind_info'] ? $user['bind_info'] : '';//绑定信息
		
		return $user_id ? $user_id : 0;
	}
	/**
	 * 分页参数
	 * @param  [type] $count    记录总数
	 * @param  [type] $pagesize 每页数量
	 */
	protected function page_info($count, $pagesize = ''){
		$pagesize = $pagesize ? $pagesize : $this->pagesize;
		$data['page']       = $this->_get('page', '', 1);
		$data['pagesize']   = $pagesize;
		$data['total_page'] = ceil($count / $pagesize);
		$data['count']      = (int)$count;
		return $data;
	}
	//接口记录
	protected function logs($status, $info, $return_data){
		$data['app_id']      = $this->app_id ? $this->app_id : 0;
		$data['authkey']     = $this->app_sign ? $this->app_sign : '';
		$data['authtime']    = $this->app_authtime ? $this->app_authtime : '';
		$data['app_version'] = $this->app_version ? $this->app_version : '';
		$data['app_type']    = $this->app_type ? $this->app_type : '';
		$data['app_imei']    = $this->app_imei ? $this->app_imei : '';
		$data['app_device']  = $this->app_device ? $this->app_device : '';
		$data['app_os']      = $this->app_os ? $this->app_os : '';
		$data['app_token']   = $this->app_token ? $this->app_token : '';
		$data['module']      = strtolower(request()->controller());
		$data['action']      = strtolower(request()->action());
		$data['params']      = 'api_sign_url_str:' . $this->app_sign_url_str  . "\r\napi_sign:" . $this->api_sign  . "\r\nGET:" . print_r($_GET,true) . "\r\nPOST:" . print_r($_POST, true);
		//请求返回数据信息
		$data['return_status'] = $status;
		$data['return_info']   = $info;
		$data['return_data']   = '';//print_r($return_data,true);
		$data['create_time']   = time();
		if(conf('api_logs_open', 'api')){
			db('AppLogs')->insert($data);
		}
	}
	protected function success($info = '', $data = '', $status = 200){
		$this->logs($status, $info, $data);
		$json['data']   = $data ? $data : null;
		$json['status'] = $status;
		$json['info']   = $info;
		header('Content-Type:application/json; charset=utf-8');
		exit(json_encode($json, JSON_UNESCAPED_UNICODE));
	}
	protected function error($info = '', $data = '', $status = 400){
		$this->logs($status, $info, $data);
		$json['data']   = $data ? $data : null;
		$json['status'] = $status;
		$json['info']   = $info;
		header('Content-Type:application/json; charset=utf-8');
		exit(json_encode($json, JSON_UNESCAPED_UNICODE));
	}
}